/**
 * 蓝牙通信模块
 * 基于经颅电刺激治疗仪蓝牙协议实现（更新版）
 */

class BluetoothManager {
  constructor() {
    this.deviceId = '';
    this.deviceName = '';
    this.serviceId = 'FEE0';
    this.writeCharacteristicId = 'FEE2';
    this.notifyCharacteristicId = 'FEE4';
    this.readCharacteristicId = 'FEE6';
    this.connected = false;
    this.heartbeatTimer = null;
    this.receiveBuffer = [];
    this.callbacks = {};
    this.isReceivingFrame = false;
    this.receivedFrame = [];
    this.bluetoothAdapterState = false; // 添加蓝牙适配器状态
  }

  // 初始化蓝牙适配器
  async initBluetooth() {
    return new Promise((resolve, reject) => {
      wx.openBluetoothAdapter({
        success: () => {
          console.log('蓝牙适配器初始化成功');
          this.bluetoothAdapterState = true; // 记录蓝牙适配器状态
          // 监听蓝牙适配器状态变化
          wx.onBluetoothAdapterStateChange((res) => {
            this.bluetoothAdapterState = res.available;
            if (!res.available) {
              console.log('蓝牙适配器已关闭');
              // 蓝牙适配器关闭时断开连接
              if (this.connected) {
                this.disconnect();
              }
            }
          });
          resolve(true);
        },
        fail: (err) => {
          console.error('蓝牙适配器初始化失败:', err);
          this.bluetoothAdapterState = false;
          reject(err);
        }
      });
    });
  }

  // 扫描设备
  async scanDevices() {
    return new Promise((resolve, reject) => {
      // 检查蓝牙适配器状态
      if (!this.bluetoothAdapterState) {
        reject(new Error('蓝牙适配器未初始化'));
        return;
      }
      
      const devices = [];
      
      wx.startBluetoothDevicesDiscovery({
        allowDuplicatesKey: false,
        success: () => {
          wx.onBluetoothDeviceFound((res) => {
            res.devices.forEach(device => {
              // 放宽设备名称过滤条件，支持更多设备
              if (device.name && (device.name.includes('BLE') )) {
                console.log('发现设备:', device);
                // 避免重复添加相同设备
                if (!devices.find(d => d.deviceId === device.deviceId)) {
                  devices.push(device);
                }
              }
            });
          });
          
          // 5秒后停止扫描
          setTimeout(() => {
            wx.stopBluetoothDevicesDiscovery({
              success: () => {
                console.log('停止扫描成功');
              },
              fail: (err) => {
                console.error('停止扫描失败:', err);
              }
            });
            resolve(devices);
          }, 5000);
        },
        fail: (err) => {
          console.error('开始扫描失败:', err);
          reject(err);
        }
      });
    });
  }

  // 连接设备
  async connectDevice(deviceId) {
    return new Promise((resolve, reject) => {
      // 检查蓝牙适配器状态
      if (!this.bluetoothAdapterState) {
        reject(new Error('蓝牙适配器未初始化'));
        return;
      }
      
      wx.createBLEConnection({
        deviceId,
        timeout: 10000, // 增加连接超时时间
        success: () => {
          this.deviceId = deviceId;
          console.log('设备连接成功');
          
          // 获取服务
          this.getBLEDeviceServices().then(() => {
            // 启用通知
            this.enableNotification().then(() => {
              // 握手
              this.handshake().then(() => {
                this.connected = true;
                // 连接成功后只心跳一次
                // this.heartbeatOnce();
                resolve(true);
              }).catch(reject);
            }).catch(reject);
          }).catch(reject);
        },
        fail: (err) => {
          console.error('设备连接失败:', err);
          reject(err);
        }
      });
    });
  }

  // 获取设备服务
  async getBLEDeviceServices() {
    return new Promise((resolve, reject) => {
      wx.getBLEDeviceServices({
        deviceId: this.deviceId,
        success: (res) => {
          console.log('获取服务成功:', res.services);
          const s = res.services.find(v => v.uuid.indexOf('FFF0') > -1);
          this.serviceId = s.uuid;
          this.getCharacteristics().then(resolve).catch(reject);
        },
        fail: reject
      });
    });
  }

  // 获取特征值
  async getCharacteristics() {
    return new Promise((resolve, reject) => {
      wx.getBLEDeviceCharacteristics({
        deviceId: this.deviceId,
        serviceId: this.serviceId,
        success: (res) => {
          console.log('获取特征值成功:', res.characteristics);
          const allCharacteristics = res.characteristics;
          this.writeCharacteristicId = allCharacteristics.find(characteristic => characteristic.properties.write).uuid;
          this.notifyCharacteristicId = allCharacteristics.find(characteristic => characteristic.properties.notify).uuid;
          this.readCharacteristicId = allCharacteristics.find(characteristic => characteristic.properties.read).uuid;
          console.log('write id:', this.writeCharacteristicId)
          console.log('notify id:', this.notifyCharacteristicId)
          console.log('read id:', this.readCharacteristicId)

          resolve(true);
        },
        fail: reject
      });
    });
  }

  // 启用通知
  async enableNotification() {
    console.log('启用通知...');
    return new Promise((resolve, reject) => {
      wx.notifyBLECharacteristicValueChange({
        deviceId: this.deviceId,
        serviceId: this.serviceId,
        characteristicId: this.notifyCharacteristicId,
        state: true,
        success: (r) => {
            console.log('notifyBLECharacteristicValueChange success', r.errMsg)

          // 监听数据变化
          wx.onBLECharacteristicValueChange((res) => {
            this.handleReceiveData(res.value);
          });
          resolve(true);
        },
        fail: reject
      });
    });
  }

  // 握手
  async handshake() {
    // 发送故障查询命令作为握手
    return this.sendCommand(0x07D0, []);
  }

  // 发送命令
  async sendCommand(cmd, data = []) {
    return new Promise((resolve, reject) => {
      const frame = this.buildFrame(cmd, data);
      const buffer = new ArrayBuffer(frame.length);
      const uint8Array = new Uint8Array(buffer);
      
      for (let i = 0; i < frame.length; i++) {
        uint8Array[i] = frame[i];
      }

      // 打印完整的帧数据（格式：AA5555AA 6A 04 05 DC 00 00 crc）
      let frameStr = '';
      for (let i = 0; i < frame.length; i++) {
        frameStr += frame[i].toString(16).padStart(2, '0').toUpperCase() + ' ';
      }
      console.log('发送蓝牙帧:', frameStr.trim());
      
      wx.writeBLECharacteristicValue({
        deviceId: this.deviceId,
        serviceId: this.serviceId,
        characteristicId: this.writeCharacteristicId,
        value: buffer,
        success: () => {
          console.log('命令发送成功:', cmd.toString(16), '数据:', data);
          resolve(true);
        },
        fail: (err) => {
          console.error('命令发送失败:', cmd.toString(16), err);
          reject(err);
        }
      });
    });
  }

  // 构建数据帧 (根据新协议)
  buildFrame(cmd, data) {
    // 新协议帧格式: 0xAA5555AA 6A 长度 CMD(2B) DATA CRC16
    const frame = [0xAA, 0x55, 0x55, 0xAA]; // 帧头
    frame.push(0x6A); // 协议号
    
    const dataLength = 2 + data.length; // CMD(2B) + DATA
    frame.push(dataLength); // 数据长度
    
    // 命令 (大端)
    frame.push((cmd >> 8) & 0xFF);
    frame.push(cmd & 0xFF);
    
    // 数据
    frame.push(...data);
    
    // 计算CRC16
    const crc = this.crc16(frame.slice(4)); // 从协议号开始计算CRC
    // CRC16低字节在前
    frame.push(crc & 0xFF);
    frame.push((crc >> 8) & 0xFF);
    
    return frame;
  }

  // CRC16-IBM 计算 (根据技术文档修正)
  crc16(data) {
    let crc = 0xFFFF;
    for (let i = 0; i < data.length; i++) {
      crc ^= data[i];
      for (let j = 0; j < 8; j++) {
        if (crc & 1) {
          crc = (crc >> 1) ^ 0xA001;
        } else {
          crc >>= 1;
        }
      }
    }
    return crc; // 低字节在前，但返回值已经是正确的
  }

  // 处理接收数据
  handleReceiveData(buffer) {
    console.log('原始接收数据:', buffer);
    const data = new Uint8Array(buffer);
    console.log('转换为Uint8Array:', data);
    // 将新数据添加到缓冲区
    this.receiveBuffer.push(...data);

    
    // 持续解析帧直到缓冲区数据不足
    while (this.receiveBuffer.length >= 9) { // 最小帧长度: 帧头(4) + 协议号(1) + 长度(1) + CMD(2) + CRC(2)
      // 查找帧头
      let headerIndex = -1;
      for (let i = 0; i <= this.receiveBuffer.length - 4; i++) {
        if (this.receiveBuffer[i] === 0xAA && 
            this.receiveBuffer[i+1] === 0x55 && 
            this.receiveBuffer[i+2] === 0x55 && 
            this.receiveBuffer[i+3] === 0xAA) {
          headerIndex = i;
          break;
        }
      }
      
      if (headerIndex === -1) {
        // 没有找到帧头，清空缓冲区或保留最后几个字节
        if (this.receiveBuffer.length > 3) {
          this.receiveBuffer = this.receiveBuffer.slice(-3);
        } else {
          this.receiveBuffer = [];
        }
        break;
      }
      
      // 如果帧头不在开头，移除前面的无效数据
      if (headerIndex > 0) {
        this.receiveBuffer = this.receiveBuffer.slice(headerIndex);
      }
      
      // 检查是否至少有帧头+协议号+长度字段
      if (this.receiveBuffer.length < 7) {
        break; // 等待更多数据
      }
      
      const protocol = this.receiveBuffer[4];
      const length = this.receiveBuffer[5];
      
      // 验证协议号
      if (protocol !== 0x6A) {
        // 协议号不匹配，移除帧头继续查找
        this.receiveBuffer = this.receiveBuffer.slice(4);
        continue;
      }
      
      // 计算完整帧所需的长度: 帧头(4) + 协议号(1) + 长度(1) + 数据(length) + CRC(2)
      const frameLength = 4 + 1 + 1 + length + 2;
      
      // 检查缓冲区是否有完整帧
      if (this.receiveBuffer.length < frameLength) {
        break; // 等待更多数据
      }
      
      // 提取完整帧
      const frame = this.receiveBuffer.slice(0, frameLength);
      this.receiveBuffer = this.receiveBuffer.slice(frameLength);
      
      // 验证CRC
      const frameData = frame.slice(4, -2); // 从协议号到数据部分
      const receivedCRC = (frame[frame.length-1] << 8) | frame[frame.length-2]; // 低字节在前
      const calculatedCRC = this.crc16(frameData);
      
      if (receivedCRC === calculatedCRC) {
        this.parseFrame(frame);
      } else {
        console.warn('CRC校验失败，丢弃帧');
      }
    }
  }

  // 解析数据帧
  parseFrame(frame) {
    // 打印完整的接收帧数据
    let frameStr = '';
    for (let i = 0; i < frame.length; i++) {
      frameStr += frame[i].toString(16).padStart(2, '0').toUpperCase() + ' ';
    }
    console.log('接收蓝牙帧:', frameStr.trim());
    
    const cmd = (frame[6] << 8) | frame[7]; // 大端
    const data = frame.slice(8, -2); // 去掉帧头、协议号、长度、CMD、CRC
    
    console.log('收到命令:', cmd.toString(16), '数据长度:', data.length, '数据:', data);
    
    switch (cmd) {
      case 0x03E8: // 设备开关状态
        this.handleDeviceStatusResponse(data);
        break;
      case 0x03E9: // 运行模式
        this.handleModeResponse(data);
        break;
      case 0x03EA: // 电流强度
        this.handleCurrentResponse(data);
        break;
      case 0x03EB: // 运行频率
        this.handleFrequencyResponse(data);
        break;
      case 0x03EC: // 按摩时间
        this.handleTimeResponse(data);
        break;
      case 0x05D8: // 阻抗大小 (根据新文档修正)
        console.log('收到阻抗响应');
        this.handleImpedanceResponse(data);
        break;
      case 0x05D9: // 实际电流 (根据新文档修正)
        this.handleActualCurrentResponse(data);
        break;
      case 0x05DC: // 电池电压 (根据新文档修正)
        console.log('收到电池响应');
        this.handleBatteryResponse(data);
        break;
      case 0x07D0: // 故障位域
        this.handleFaultResponse(data);
        break;
      default:
        console.log('未知命令:', cmd.toString(16));
    }
  }

  // 处理设备状态响应
  handleDeviceStatusResponse(data) {
    if (data.length >= 2) {
      const status = (data[0] << 8) | data[1]; // 大端
      const working = status === 1;
      
      if (this.callbacks.onStatusUpdate) {
        this.callbacks.onStatusUpdate({ working });
      }
    }
  }

  // 处理运行模式响应
  handleModeResponse(data) {
    if (data.length >= 2) {
      const mode = (data[0] << 8) | data[1]; // 大端
      
      if (this.callbacks.onModeUpdate) {
        this.callbacks.onModeUpdate(mode);
      }
    }
  }

  // 处理电流强度响应
  handleCurrentResponse(data) {
    if (data.length >= 2) {
      const current = (data[0] << 8) | data[1]; // 大端
      // 电流强度倍率: 1 (0-50 → 0-2 mA)
      const actualCurrent = current * 0.04; // 0-50对应0-2mA
      
      if (this.callbacks.onCurrentUpdate) {
        this.callbacks.onCurrentUpdate(actualCurrent);
      }
    }
  }

  // 处理运行频率响应
  handleFrequencyResponse(data) {
    if (data.length >= 2) {
      const frequency = (data[0] << 8) | data[1]; // 大端
      // 频率倍率: 10 (0-1000 → 0-100 Hz)
      const actualFrequency = frequency / 10; // 0-1000对应0-100Hz
      
      if (this.callbacks.onFrequencyUpdate) {
        this.callbacks.onFrequencyUpdate(actualFrequency);
      }
    }
  }

  // 处理按摩时间响应
  handleTimeResponse(data) {
    if (data.length >= 2) {
      const time = (data[0] << 8) | data[1]; // 大端
      
      if (this.callbacks.onTimeUpdate) {
        this.callbacks.onTimeUpdate(time);
      }
    }
  }

  // 处理阻抗响应
  handleImpedanceResponse(data) {
    console.log('处理阻抗响应，数据长度:', data.length, '数据:', data);
    if (data.length >= 4) {
      // float 采用 IEEE-754 单精度，大端顺序
      const buffer = new ArrayBuffer(4);
      const view = new DataView(buffer);
      view.setUint8(0, data[0]);
      view.setUint8(1, data[1]);
      view.setUint8(2, data[2]);
      view.setUint8(3, data[3]);
      const impedance = view.getFloat32(0, false); // 大端
      
      console.log('解析到的阻抗值:', impedance, 'Ω');
      if (this.callbacks.onImpedanceUpdate) {
        this.callbacks.onImpedanceUpdate(impedance);
      }
    } else {
      console.warn('阻抗响应数据长度不足:', data.length);
    }
  }

  // 处理实际电流响应
  handleActualCurrentResponse(data) {
    if (data.length >= 4) {
      // float 采用 IEEE-754 单精度，大端顺序
      const buffer = new ArrayBuffer(4);
      const view = new DataView(buffer);
      view.setUint8(0, data[0]);
      view.setUint8(1, data[1]);
      view.setUint8(2, data[2]);
      view.setUint8(3, data[3]);
      const current = view.getFloat32(0, false); // 大端
      
      if (this.callbacks.onActualCurrentUpdate) {
        this.callbacks.onActualCurrentUpdate(current);
      }
    }
  }

  // 处理电池响应
  handleBatteryResponse(data) {
    console.log('处理电池响应，数据长度:', data.length, '数据:', data);
    if (data.length >= 4) {
      // float 采用 IEEE-754 单精度，大端顺序
      const buffer = new ArrayBuffer(4);
      const view = new DataView(buffer);
      view.setUint8(0, data[0]);
      view.setUint8(1, data[1]);
      view.setUint8(2, data[2]);
      view.setUint8(3, data[3]);
      const battery = view.getFloat32(0, false); // 大端
      
      console.log('解析到的电池电量:', battery, '%');
      if (this.callbacks.onBatteryUpdate) {
        this.callbacks.onBatteryUpdate({ level: battery });
      }
    } else {
      console.warn('电池响应数据长度不足:', data.length);
    }
  }

  // 处理故障响应
  handleFaultResponse(data) {
    if (data.length >= 2) {
      const fault = (data[0] << 8) | data[1]; // 大端
      
      if (this.callbacks.onFaultUpdate) {
        this.callbacks.onFaultUpdate(fault);
      }
    }
  }

  // 心跳一次
  async heartbeatOnce() {
    if (this.connected) {
      try {
        console.log('执行一次心跳查询...');
        // 分开发送命令，避免同时发送
        await this.queryBattery();
        await new Promise(resolve => setTimeout(resolve, 200)); // 延迟200ms
        await this.queryImpedance();
        console.log('心跳查询完成');
      } catch (error) {
        console.error('心跳查询失败:', error);
      }
    }
  }


  // 查询电池
  async queryBattery() {
    console.log('查询电池电量...');
    // 直接使用命令方式查询，更可靠
    return this.sendCommand(0x05DC, [0x00, 0x00, 0x00, 0x00]);
  }

  // 查询阻抗值
  async queryImpedance() {
    console.log('查询阻抗值...');
    // 直接使用命令方式查询，更可靠
    return this.sendCommand(0x05D8, [0x00, 0x00, 0x00, 0x00]);
  }

  // 读取电池特征值
  async readBatteryCharacteristic() {
    return new Promise((resolve, reject) => {
      // 尝试读取电池特征值
      wx.readBLECharacteristicValue({
        deviceId: this.deviceId,
        serviceId: this.serviceId,
        characteristicId: this.readCharacteristicId, // 标准电池特征值UUID
        success: (res) => {
          // 解析电池电量数据
          if (res.value) {
            const data = new Uint8Array(res.value);
            if (data.length > 0) {
              resolve(data[0]); // 电池电量通常在0-100之间
            } else {
              resolve(null);
            }
          } else {
            resolve(null);
          }
        },
        fail: (err) => {
          console.warn('读取电池特征值失败:', err);
          resolve(null); // 修复：添加缺失的resolve
        }
      });
    });
  }

  // 读取阻抗特征值
  async readImpedanceCharacteristic() {
    return new Promise((resolve, reject) => {
      // 尝试读取阻抗特征值
      wx.readBLECharacteristicValue({
        deviceId: this.deviceId,
        serviceId: this.serviceId,
        characteristicId: this.readCharacteristicId, // 设备特定的阻抗特征值
        success: (res) => {
          // 解析阻抗数据
          if (res.value) {
            const data = new Uint8Array(res.value);
            if (data.length >= 4) {
              // 解析为浮点数
              const buffer = new ArrayBuffer(4);
              const view = new DataView(buffer);
              view.setUint8(0, data[0]);
              view.setUint8(1, data[1]);
              view.setUint8(2, data[2]);
              view.setUint8(3, data[3]);
              const impedance = view.getFloat32(0, false); // 大端
              resolve(impedance);
            } else {
              resolve(null);
            }
          } else {
            resolve(null);
          }
        },
        fail: (err) => {
          console.warn('读取阻抗特征值失败:', err);
          resolve(null);
        }
      });
    });
  }

  // 设置治疗参数 
  async setTreatmentParams(params) {
    // 设置模式: 1=直流正向 2=直流负向 3=交流
    const modeMap = { 'tDCS+': 1, 'tDCS-': 2, 'tACS': 3 };
    const mode = modeMap[params.mode] || 1;
    await this.sendCommand(0x03E9, [(mode >> 8) & 0xFF, mode & 0xFF]);
    
    // 设置电流强度 (0-50对应0-2mA，步进0.04mA)
    const currentLevel = Math.round(params.current / 0.04);
    await this.sendCommand(0x03EA, [(currentLevel >> 8) & 0xFF, currentLevel & 0xFF]);
    
    // 设置频率 (0-1000对应0.1-100Hz，步进0.1Hz)
    const frequencyLevel = Math.round(params.frequency * 10);
    await this.sendCommand(0x03EB, [(frequencyLevel >> 8) & 0xFF, frequencyLevel & 0xFF]);
    
    // 设置时间 (分钟)
    const timeMinutes = params.time;
    await this.sendCommand(0x03EC, [(timeMinutes >> 8) & 0xFF, timeMinutes & 0xFF]);
    
    return true;
  }

  // 开始治疗
  async startTreatment() {
    return this.sendCommand(0x03E8, [0x00, 0x01]); // 设备开关=运行
  }

  // 暂停治疗
  async pauseTreatment() {
    // 暂停功能需要通过停止治疗实现
    return this.stopTreatment();
  }

  // 继续治疗
  async resumeTreatment() {
    // 继续功能需要重新开始治疗
    return this.startTreatment();
  }

  // 停止治疗
  async stopTreatment() {
    return this.sendCommand(0x03E8, [0x00, 0x00]); // 设备开关=待机
  }

  // 紧急停止治疗
  async emergencyStop() {
    return this.sendCommand(0x03E8, [0x00, 0x00]); // 设备开关=待机
  }

  // 断开连接
  disconnect() {
    // 清除心跳定时器
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer);
      this.heartbeatTimer = null;
    }
    
    // 关闭BLE连接
    if (this.deviceId) {
      wx.closeBLEConnection({
        deviceId: this.deviceId,
        success: () => {
          console.log('BLE连接已关闭');
        },
        fail: (err) => {
          console.error('关闭BLE连接失败:', err);
        }
      });
    }
    
    // 重置状态
    this.connected = false;
    this.deviceId = '';
    this.receiveBuffer = [];
    // 不重置蓝牙适配器状态，保持适配器开启状态以便重新连接
  }

  // 设置回调
  setCallbacks(callbacks) {
    this.callbacks = callbacks;
  }
}

module.exports = BluetoothManager;